WebCodecs-এর শক্তি উন্মোচন করুন! VideoFrame প্লেন ব্যবহার করে ভিডিও ফ্রেম ডেটা অ্যাক্সেস এবং ম্যানিপুলেট করার একটি সম্পূর্ণ নির্দেশিকা। ব্রাউজারে উন্নত ভিডিও প্রসেসিংয়ের জন্য পিক্সেল ফরম্যাট, মেমরি লেআউট এবং ব্যবহারিক প্রয়োগ সম্পর্কে জানুন।
WebCodecs ভিডিওফ্রেম প্লেন: ভিডিও ফ্রেম ডেটা অ্যাক্সেসের গভীর বিশ্লেষণ
WebCodecs ওয়েব-ভিত্তিক মিডিয়া প্রসেসিংয়ে একটি যুগান্তকারী পরিবর্তন এনেছে। এটি মিডিয়ার মৌলিক উপাদানগুলিতে নিম্ন-স্তরের অ্যাক্সেস সরবরাহ করে, যা ডেভেলপারদের সরাসরি ব্রাউজারে অত্যাধুনিক অ্যাপ্লিকেশন তৈরি করতে সক্ষম করে। WebCodecs-এর অন্যতম শক্তিশালী বৈশিষ্ট্য হলো VideoFrame অবজেক্ট, এবং এর মধ্যে থাকা VideoFrame প্লেনগুলো যা ভিডিও ফ্রেমের র' (raw) পিক্সেল ডেটা প্রকাশ করে। এই নিবন্ধটি উন্নত ভিডিও ম্যানিপুলেশনের জন্য VideoFrame প্লেন বোঝা এবং ব্যবহার করার জন্য একটি সম্পূর্ণ নির্দেশিকা প্রদান করে।
VideoFrame অবজেক্ট বোঝা
প্লেন নিয়ে আলোচনা করার আগে, আসুন VideoFrame অবজেক্টটি সম্পর্কে সংক্ষেপে জেনে নেওয়া যাক। একটি VideoFrame ভিডিওর একটি একক ফ্রেমকে প্রতিনিধিত্ব করে। এটি ডিকোড করা (বা এনকোড করা) ভিডিও ডেটা এবং এর সাথে সম্পর্কিত মেটাডেটা যেমন টাইমস্ট্যাম্প, সময়কাল এবং ফরম্যাট তথ্যকে অন্তর্ভুক্ত করে। VideoFrame API নিম্নলিখিত পদ্ধতিগুলো সরবরাহ করে:
- পিক্সেল ডেটা পড়া: এখানেই প্লেনগুলির ভূমিকা আসে।
- ফ্রেম কপি করা: বিদ্যমান
VideoFrameঅবজেক্ট থেকে নতুন অবজেক্ট তৈরি করা। - ফ্রেম বন্ধ করা: ফ্রেম দ্বারা ধারণ করা অন্তর্নিহিত রিসোর্সগুলো মুক্ত করা।
VideoFrame অবজেক্টটি ডিকোডিং প্রক্রিয়া চলাকালীন তৈরি হয়, সাধারণত একটি VideoDecoder দ্বারা, অথবা কাস্টম ফ্রেম তৈরি করার সময় ম্যানুয়ালি তৈরি করা হয়।
VideoFrame প্লেন কি?
একটি VideoFrame-এর পিক্সেল ডেটা প্রায়শই একাধিক প্লেনে সংগঠিত থাকে, বিশেষ করে YUV-এর মতো ফরম্যাটে। প্রতিটি প্লেন ছবির একটি ভিন্ন উপাদানকে প্রতিনিধিত্ব করে। উদাহরণস্বরূপ, একটি YUV420 ফরম্যাটে তিনটি প্লেন থাকে:
- Y (Luma): ছবির উজ্জ্বলতা (luminance) প্রতিনিধিত্ব করে। এই প্লেনে গ্রেস্কেল তথ্য থাকে।
- U (Cb): নীল-পার্থক্য ক্রোমা উপাদানকে প্রতিনিধিত্ব করে।
- V (Cr): লাল-পার্থক্য ক্রোমা উপাদানকে প্রতিনিধিত্ব করে।
RGB ফরম্যাটগুলো দেখতে সহজ মনে হলেও, কিছু ক্ষেত্রে একাধিক প্লেন ব্যবহার করতে পারে। প্লেনের সংখ্যা এবং তাদের অর্থ সম্পূর্ণরূপে VideoFrame-এর VideoPixelFormat-এর উপর নির্ভর করে।
প্লেন ব্যবহারের সুবিধা হলো এটি নির্দিষ্ট রঙের উপাদানগুলিতে কার্যকর অ্যাক্সেস এবং ম্যানিপুলেশনের অনুমতি দেয়। উদাহরণস্বরূপ, আপনি হয়তো শুধুমাত্র উজ্জ্বলতা (Y প্লেন) পরিবর্তন করতে চান, রঙকে (U এবং V প্লেন) প্রভাবিত না করে।
VideoFrame প্লেন অ্যাক্সেস করা: API
VideoFrame API প্লেন ডেটা অ্যাক্সেস করার জন্য নিম্নলিখিত পদ্ধতি সরবরাহ করে:
copyTo(destination, options):VideoFrame-এর বিষয়বস্তু একটি গন্তব্যে কপি করে, যা অন্য একটিVideoFrame, একটিCanvasImageBitmap, বা একটিArrayBufferViewহতে পারে।optionsঅবজেক্টটি নিয়ন্ত্রণ করে কোন প্লেনগুলো কীভাবে কপি করা হবে। এটি প্লেন অ্যাক্সেসের প্রাথমিক প্রক্রিয়া।
copyTo পদ্ধতির options অবজেক্টটি আপনাকে ভিডিও ফ্রেম ডেটার জন্য লেআউট এবং টার্গেট নির্দিষ্ট করতে দেয়। মূল বৈশিষ্ট্যগুলির মধ্যে রয়েছে:
format: কপি করা ডেটার কাঙ্ক্ষিত পিক্সেল ফরম্যাট। এটি মূলVideoFrame-এর ফরম্যাটের মতোই হতে পারে বা একটি ভিন্ন ফরম্যাটও হতে পারে (যেমন, YUV থেকে RGB-তে রূপান্তর)।codedWidthএবংcodedHeight: পিক্সেল এককে ভিডিও ফ্রেমের প্রস্থ এবং উচ্চতা।layout: একটি অ্যারে যা মেমরিতে প্রতিটি প্লেনের লেআউট বর্ণনা করে। অ্যারের প্রতিটি অবজেক্ট নির্দিষ্ট করে:offset: ডেটা বাফারের শুরু থেকে প্লেনের ডেটার শুরু পর্যন্ত বাইট এককে দূরত্ব।stride: প্লেনের প্রতিটি সারির শুরুর মধ্যে বাইটের সংখ্যা। প্যাডিং সামলানোর জন্য এটি অত্যন্ত গুরুত্বপূর্ণ।
আসুন একটি YUV420 VideoFrame একটি র' বাফারে কপি করার উদাহরণ দেখি:
async function copyYUV420ToBuffer(videoFrame, buffer) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
// YUV420-তে ৩টি প্লেন থাকে: Y, U, এবং V
const yPlaneSize = width * height;
const uvPlaneSize = width * height / 4;
const layout = [
{ offset: 0, stride: width }, // Y প্লেন
{ offset: yPlaneSize, stride: width / 2 }, // U প্লেন
{ offset: yPlaneSize + uvPlaneSize, stride: width / 2 } // V প্লেন
];
await videoFrame.copyTo(buffer, {
format: 'I420',
codedWidth: width,
codedHeight: height,
layout: layout
});
videoFrame.close(); // রিসোর্স মুক্ত করা গুরুত্বপূর্ণ
}
ব্যাখ্যা:
- আমরা
widthএবংheight-এর উপর ভিত্তি করে প্রতিটি প্লেনের আকার গণনা করি। Y সম্পূর্ণ রেজোলিউশনের, যেখানে U এবং V সাবস্যাম্পলড (4:2:0)। layoutঅ্যারে মেমরি লেআউটকে সংজ্ঞায়িত করে।offsetনির্দিষ্ট করে প্রতিটি প্লেন বাফারে কোথায় শুরু হয়, এবংstrideনির্দিষ্ট করে সেই প্লেনের পরবর্তী সারিতে যাওয়ার জন্য কত বাইট লাফ দিতে হবে।formatঅপশনটি 'I420'-তে সেট করা হয়েছে, যা একটি সাধারণ YUV420 ফরম্যাট।- গুরুত্বপূর্ণভাবে, কপি করার পরে, রিসোর্স মুক্ত করার জন্য
videoFrame.close()কল করা হয়।
পিক্সেল ফরম্যাট: সম্ভাবনার এক নতুন জগৎ
VideoFrame প্লেন নিয়ে কাজ করার জন্য পিক্সেল ফরম্যাট বোঝা অপরিহার্য। VideoPixelFormat সংজ্ঞায়িত করে যে কীভাবে রঙের তথ্য ভিডিও ফ্রেমের মধ্যে এনকোড করা হয়েছে। এখানে কিছু সাধারণ পিক্সেল ফরম্যাট রয়েছে যা আপনার সামনে আসতে পারে:
- I420 (YUV420p): একটি প্ল্যানার YUV ফরম্যাট যেখানে Y, U, এবং V উপাদানগুলো পৃথক প্লেনে সংরক্ষণ করা হয়। U এবং V উভয় অনুভূমিক এবং উল্লম্ব দিকে ২ গুণক দ্বারা সাবস্যাম্পল করা হয়। এটি একটি খুব সাধারণ এবং কার্যকর ফরম্যাট।
- NV12 (YUV420sp): একটি সেমি-প্ল্যানার YUV ফরম্যাট যেখানে Y একটি প্লেনে এবং U এবং V উপাদানগুলো একটি দ্বিতীয় প্লেনে ইন্টারলিভড (interleaved) থাকে।
- RGBA: লাল, সবুজ, নীল এবং আলফা উপাদানগুলো একটি একক প্লেনে সংরক্ষণ করা হয়, সাধারণত প্রতিটি উপাদানের জন্য ৮ বিট (প্রতি পিক্সেলে ৩২ বিট) করে। উপাদানগুলোর ক্রম ভিন্ন হতে পারে (যেমন, BGRA)।
- RGB565: লাল, সবুজ এবং নীল উপাদানগুলো একটি একক প্লেনে সংরক্ষণ করা হয়, যেখানে লালের জন্য ৫ বিট, সবুজের জন্য ৬ বিট এবং নীলের জন্য ৫ বিট (প্রতি পিক্সেলে ১৬ বিট) থাকে।
- GRAYSCALE: প্রতিটি পিক্সেলের জন্য একটি একক লুমা (উজ্জ্বলতা) মান সহ গ্রেস্কেল ছবি প্রতিনিধিত্ব করে।
VideoFrame.format প্রপার্টি আপনাকে একটি নির্দিষ্ট ফ্রেমের পিক্সেল ফরম্যাট জানাবে। প্লেন অ্যাক্সেস করার চেষ্টা করার আগে এই প্রপার্টিটি পরীক্ষা করে নিশ্চিত হন। সমর্থিত ফরম্যাটের সম্পূর্ণ তালিকার জন্য আপনি WebCodecs স্পেসিফিকেশন দেখতে পারেন।
ব্যবহারিক প্রয়োগ
VideoFrame প্লেন অ্যাক্সেস করা ব্রাউজারে উন্নত ভিডিও প্রসেসিংয়ের জন্য বিস্তৃত সম্ভাবনার দ্বার উন্মুক্ত করে। এখানে কিছু উদাহরণ দেওয়া হলো:
১. রিয়েল-টাইম ভিডিও এফেক্টস
আপনি VideoFrame-এর পিক্সেল ডেটা ম্যানিপুলেট করে রিয়েল-টাইম ভিডিও এফেক্ট প্রয়োগ করতে পারেন। উদাহরণস্বরূপ, আপনি একটি RGBA ফ্রেমের প্রতিটি পিক্সেলের R, G, এবং B উপাদানগুলোর গড় করে একটি গ্রেস্কেল ফিল্টার প্রয়োগ করতে পারেন এবং তারপরে তিনটি উপাদানকে সেই গড় মানে সেট করতে পারেন। আপনি সেপিয়া টোন এফেক্ট তৈরি করতে বা উজ্জ্বলতা এবং কনট্রাস্ট সামঞ্জস্য করতে পারেন।
async function applyGrayscale(videoFrame) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
const buffer = new ArrayBuffer(width * height * 4); // RGBA
const rgba = new Uint8ClampedArray(buffer);
await videoFrame.copyTo(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height
});
for (let i = 0; i < rgba.length; i += 4) {
const r = rgba[i];
const g = rgba[i + 1];
const b = rgba[i + 2];
const gray = (r + g + b) / 3;
rgba[i] = gray; // লাল
rgba[i + 1] = gray; // সবুজ
rgba[i + 2] = gray; // নীল
}
// পরিবর্তিত ডেটা থেকে একটি নতুন VideoFrame তৈরি করুন।
const newFrame = new VideoFrame(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height,
timestamp: videoFrame.timestamp,
duration: videoFrame.duration
});
videoFrame.close(); // আসল ফ্রেমটি মুক্ত করুন
return newFrame;
}
২. কম্পিউটার ভিশন অ্যাপ্লিকেশন
VideoFrame প্লেন কম্পিউটার ভিশন কাজের জন্য প্রয়োজনীয় পিক্সেল ডেটাতে সরাসরি অ্যাক্সেস সরবরাহ করে। আপনি এই ডেটা ব্যবহার করে অবজেক্ট ডিটেকশন, ফেসিয়াল রিকগনিশন, মোশন ট্র্যাকিং এবং আরও অনেক কিছুর জন্য অ্যালগরিদম প্রয়োগ করতে পারেন। আপনি আপনার কোডের পারফরম্যান্স-নির্ভর অংশগুলির জন্য WebAssembly ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, আপনি একটি রঙিন VideoFrame-কে গ্রেস্কেলে রূপান্তর করতে পারেন এবং তারপরে ছবির প্রান্ত সনাক্ত করতে একটি এজ ডিটেকশন অ্যালগরিদম (যেমন, সোবেল অপারেটর) প্রয়োগ করতে পারেন। এটি অবজেক্ট রিকগনিশনের জন্য একটি প্রি-প্রসেসিং ধাপ হিসাবে ব্যবহার করা যেতে পারে।
৩. ভিডিও এডিটিং এবং কম্পোজিটিং
আপনি VideoFrame প্লেন ব্যবহার করে ক্রপিং, স্কেলিং, রোটেশন এবং কম্পোজিটিংয়ের মতো ভিডিও এডিটিং বৈশিষ্ট্যগুলি প্রয়োগ করতে পারেন। পিক্সেল ডেটা সরাসরি ম্যানিপুলেট করে, আপনি কাস্টম ট্রানজিশন এবং এফেক্ট তৈরি করতে পারেন।
উদাহরণস্বরূপ, আপনি একটি নতুন VideoFrame-এ পিক্সেল ডেটার শুধুমাত্র একটি অংশ কপি করে একটি VideoFrame ক্রপ করতে পারেন। আপনাকে সেই অনুযায়ী layout অফসেট এবং স্ট্রাইড সামঞ্জস্য করতে হবে।
৪. কাস্টম কোডেক এবং ট্রান্সকোডিং
যদিও WebCodecs AV1, VP9, এবং H.264-এর মতো সাধারণ কোডেকগুলির জন্য বিল্ট-ইন সমর্থন সরবরাহ করে, আপনি এটি কাস্টম কোডেক বা ট্রান্সকোডিং পাইপলাইন প্রয়োগ করতেও ব্যবহার করতে পারেন। আপনাকে এনকোডিং এবং ডিকোডিং প্রক্রিয়াটি নিজে পরিচালনা করতে হবে, তবে VideoFrame প্লেন আপনাকে র' পিক্সেল ডেটা অ্যাক্সেস এবং ম্যানিপুলেট করার অনুমতি দেয়। এটি বিশেষ ভিডিও ফরম্যাট বা বিশেষ এনকোডিং প্রয়োজনীয়তার জন্য উপযোগী হতে পারে।
৫. উন্নত বিশ্লেষণ
অন্তর্নিহিত পিক্সেল ডেটা অ্যাক্সেস করে, আপনি ভিডিও সামগ্রীর গভীর বিশ্লেষণ করতে পারেন। এর মধ্যে একটি দৃশ্যের গড় উজ্জ্বলতা পরিমাপ করা, প্রভাবশালী রঙ সনাক্ত করা বা দৃশ্যের বিষয়বস্তুতে পরিবর্তন সনাক্ত করার মতো কাজ অন্তর্ভুক্ত। এটি নিরাপত্তা, নজরদারি বা বিষয়বস্তু বিশ্লেষণের জন্য উন্নত ভিডিও বিশ্লেষণ অ্যাপ্লিকেশন সক্ষম করতে পারে।
ক্যানভাস এবং WebGL-এর সাথে কাজ করা
যদিও আপনি সরাসরি VideoFrame প্লেনে পিক্সেল ডেটা ম্যানিপুলেট করতে পারেন, প্রায়শই আপনাকে ফলাফলটি স্ক্রিনে রেন্ডার করতে হয়। CanvasImageBitmap ইন্টারফেস VideoFrame এবং <canvas> এলিমেন্টের মধ্যে একটি সেতু হিসাবে কাজ করে। আপনি একটি VideoFrame থেকে একটি CanvasImageBitmap তৈরি করতে পারেন এবং তারপরে drawImage() পদ্ধতি ব্যবহার করে এটি ক্যানভাসে আঁকতে পারেন।
async function renderVideoFrameToCanvas(videoFrame, canvas) {
const bitmap = await createImageBitmap(videoFrame);
const ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
bitmap.close(); // বিটম্যাপ রিসোর্স মুক্ত করুন
videoFrame.close(); // VideoFrame রিসোর্স মুক্ত করুন
}
আরও উন্নত রেন্ডারিংয়ের জন্য, আপনি WebGL ব্যবহার করতে পারেন। আপনি VideoFrame প্লেন থেকে পিক্সেল ডেটা WebGL টেক্সচারে আপলোড করতে পারেন এবং তারপরে এফেক্ট এবং রূপান্তর প্রয়োগ করতে শেডার ব্যবহার করতে পারেন। এটি আপনাকে উচ্চ-পারফরম্যান্স ভিডিও প্রসেসিংয়ের জন্য GPU-কে কাজে লাগানোর সুযোগ দেয়।
পারফরম্যান্স বিবেচনা
র' পিক্সেল ডেটা নিয়ে কাজ করা কম্পিউটেশনালি ইনটেনসিভ হতে পারে, তাই পারফরম্যান্স অপ্টিমাইজেশন বিবেচনা করা অত্যন্ত গুরুত্বপূর্ণ। এখানে কিছু টিপস দেওয়া হলো:
- কপি কমানো: পিক্সেল ডেটার অপ্রয়োজনীয় কপি করা এড়িয়ে চলুন। যখনই সম্ভব, অপারেশনগুলো ইন-প্লেস (in-place) করার চেষ্টা করুন।
- WebAssembly ব্যবহার করুন: আপনার কোডের পারফরম্যান্স-নির্ভর অংশগুলির জন্য WebAssembly ব্যবহার করার কথা বিবেচনা করুন। WebAssembly কম্পিউটেশনালি ইনটেনসিভ কাজের জন্য নেটিভ-এর কাছাকাছি পারফরম্যান্স সরবরাহ করতে পারে।
- মেমরি লেআউট অপ্টিমাইজ করুন: আপনার অ্যাপ্লিকেশনের জন্য সঠিক পিক্সেল ফরম্যাট এবং মেমরি লেআউট বেছে নিন। যদি আপনার ঘন ঘন পৃথক রঙের উপাদানগুলিতে অ্যাক্সেসের প্রয়োজন না হয়, তবে প্যাকড ফরম্যাট (যেমন, RGBA) ব্যবহার করার কথা বিবেচনা করুন।
- OffscreenCanvas ব্যবহার করুন: ব্যাকগ্রাউন্ড প্রসেসিংয়ের জন্য, মূল থ্রেড ব্লক করা এড়াতে
OffscreenCanvasব্যবহার করুন। - আপনার কোড প্রোফাইল করুন: আপনার কোড প্রোফাইল করতে এবং পারফরম্যান্সের বাধাগুলি সনাক্ত করতে ব্রাউজার ডেভেলপার টুল ব্যবহার করুন।
ব্রাউজার সামঞ্জস্যতা
WebCodecs এবং VideoFrame API বেশিরভাগ আধুনিক ব্রাউজারে সমর্থিত, যার মধ্যে Chrome, Firefox এবং Safari অন্তর্ভুক্ত। তবে, সমর্থনের স্তর ব্রাউজার সংস্করণ এবং অপারেটিং সিস্টেমের উপর নির্ভর করে ভিন্ন হতে পারে। আপনার টার্গেট ব্রাউজারগুলিতে আপনি যে বৈশিষ্ট্যগুলি ব্যবহার করছেন তা সমর্থিত কিনা তা নিশ্চিত করতে MDN Web Docs-এর মতো সাইটে সর্বশেষ ব্রাউজার সামঞ্জস্যতা টেবিলগুলি দেখুন। ক্রস-ব্রাউজার সামঞ্জস্যতার জন্য, ফিচার ডিটেকশন সুপারিশ করা হয়।
সাধারণ সমস্যা এবং সমাধান
VideoFrame প্লেন নিয়ে কাজ করার সময় এড়ানোর জন্য এখানে কিছু সাধারণ সমস্যা রয়েছে:
- ভুল লেআউট: নিশ্চিত করুন যে
layoutঅ্যারেটি পিক্সেল ডেটার মেমরি লেআউট সঠিকভাবে বর্ণনা করে। ভুল অফসেট বা স্ট্রাইডগুলি ছবি নষ্ট করে দিতে পারে। - বেমানান পিক্সেল ফরম্যাট: নিশ্চিত করুন যে
copyToপদ্ধতিতে আপনি যে পিক্সেল ফরম্যাটটি নির্দিষ্ট করেছেন তাVideoFrame-এর আসল ফরম্যাটের সাথে মেলে। - মেমরি লিক:
VideoFrameএবংCanvasImageBitmapঅবজেক্টগুলো ব্যবহার শেষ হওয়ার পরে সর্বদা বন্ধ করুন যাতে অন্তর্নিহিত রিসোর্সগুলো মুক্ত হয়। এটি করতে ব্যর্থ হলে মেমরি লিক হতে পারে। - অ্যাসিঙ্ক্রোনাস অপারেশন: মনে রাখবেন যে
copyToএকটি অ্যাসিঙ্ক্রোনাস অপারেশন। পিক্সেল ডেটা অ্যাক্সেস করার আগে কপি অপারেশনটি সম্পন্ন হয়েছে তা নিশ্চিত করতেawaitব্যবহার করুন। - নিরাপত্তা সীমাবদ্ধতা: ক্রস-অরিজিন ভিডিও থেকে পিক্সেল ডেটা অ্যাক্সেস করার সময় প্রযোজ্য হতে পারে এমন নিরাপত্তা সীমাবদ্ধতা সম্পর্কে সচেতন থাকুন।
উদাহরণ: YUV থেকে RGB রূপান্তর
আসুন একটি আরও জটিল উদাহরণ বিবেচনা করি: একটি YUV420 VideoFrame-কে একটি RGB VideoFrame-এ রূপান্তর করা। এর মধ্যে Y, U, এবং V প্লেন পড়া, সেগুলিকে RGB মানগুলিতে রূপান্তর করা এবং তারপরে একটি নতুন RGB VideoFrame তৈরি করা জড়িত।
এই রূপান্তরটি নিম্নলিখিত সূত্র ব্যবহার করে প্রয়োগ করা যেতে পারে:
R = Y + 1.402 * (Cr - 128)
G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
B = Y + 1.772 * (Cb - 128)
এখানে কোডটি রয়েছে:
async function convertYUV420ToRGBA(videoFrame) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
const yPlaneSize = width * height;
const uvPlaneSize = width * height / 4;
const yuvBuffer = new ArrayBuffer(yPlaneSize + 2 * uvPlaneSize);
const yuvPlanes = new Uint8ClampedArray(yuvBuffer);
const layout = [
{ offset: 0, stride: width }, // Y প্লেন
{ offset: yPlaneSize, stride: width / 2 }, // U প্লেন
{ offset: yPlaneSize + uvPlaneSize, stride: width / 2 } // V প্লেন
];
await videoFrame.copyTo(yuvPlanes, {
format: 'I420',
codedWidth: width,
codedHeight: height,
layout: layout
});
const rgbaBuffer = new ArrayBuffer(width * height * 4);
const rgba = new Uint8ClampedArray(rgbaBuffer);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const yIndex = y * width + x;
const uIndex = Math.floor(y / 2) * (width / 2) + Math.floor(x / 2) + yPlaneSize;
const vIndex = Math.floor(y / 2) * (width / 2) + Math.floor(x / 2) + yPlaneSize + uvPlaneSize;
const Y = yuvPlanes[yIndex];
const U = yuvPlanes[uIndex] - 128;
const V = yuvPlanes[vIndex] - 128;
let R = Y + 1.402 * V;
let G = Y - 0.34414 * U - 0.71414 * V;
let B = Y + 1.772 * U;
R = Math.max(0, Math.min(255, R));
G = Math.max(0, Math.min(255, G));
B = Math.max(0, Math.min(255, B));
const rgbaIndex = y * width * 4 + x * 4;
rgba[rgbaIndex] = R;
rgba[rgbaIndex + 1] = G;
rgba[rgbaIndex + 2] = B;
rgba[rgbaIndex + 3] = 255; // আলফা
}
}
const newFrame = new VideoFrame(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height,
timestamp: videoFrame.timestamp,
duration: videoFrame.duration
});
videoFrame.close(); // আসল ফ্রেমটি মুক্ত করুন
return newFrame;
}
এই উদাহরণটি VideoFrame প্লেন নিয়ে কাজ করার শক্তি এবং জটিলতা প্রদর্শন করে। এর জন্য পিক্সেল ফরম্যাট, মেমরি লেআউট এবং কালার স্পেস রূপান্তর সম্পর্কে একটি ভাল ধারণা প্রয়োজন।
উপসংহার
WebCodecs-এর VideoFrame প্লেন API ব্রাউজারে ভিডিও প্রসেসিংয়ের উপর একটি নতুন স্তরের নিয়ন্ত্রণ উন্মুক্ত করে। পিক্সেল ডেটা সরাসরি কীভাবে অ্যাক্সেস এবং ম্যানিপুলেট করতে হয় তা বোঝার মাধ্যমে, আপনি রিয়েল-টাইম ভিডিও এফেক্ট, কম্পিউটার ভিশন, ভিডিও এডিটিং এবং আরও অনেক কিছুর জন্য উন্নত অ্যাপ্লিকেশন তৈরি করতে পারেন। যদিও VideoFrame প্লেন নিয়ে কাজ করা চ্যালেঞ্জিং হতে পারে, তবে সম্ভাব্য পুরস্কারগুলি তাৎপর্যপূর্ণ। WebCodecs যেমন বিকশিত হতে থাকবে, এটি নিঃসন্দেহে মিডিয়া নিয়ে কাজ করা ওয়েব ডেভেলপারদের জন্য একটি অপরিহার্য টুল হয়ে উঠবে।
আমরা আপনাকে VideoFrame প্লেন API নিয়ে পরীক্ষা করতে এবং এর ক্ষমতাগুলি অন্বেষণ করতে উৎসাহিত করছি। অন্তর্নিহিত নীতিগুলি বোঝার মাধ্যমে এবং সর্বোত্তম অনুশীলনগুলি প্রয়োগ করার মাধ্যমে, আপনি উদ্ভাবনী এবং পারফরম্যান্ট ভিডিও অ্যাপ্লিকেশন তৈরি করতে পারেন যা ব্রাউজারে যা সম্ভব তার সীমানা ছাড়িয়ে যায়।
আরও জানুন
- MDN Web Docs on WebCodecs
- WebCodecs Specification
- GitHub-এ WebCodecs স্যাম্পল কোড রিপোজিটরি।